module ActiveBackground
  class Client < Base
    include Singleton
    
    @@server = false
    
    def initialize
    end
    
    # this method is called before every method
    def prepare
      begin
        # try to connect again if @@server is LocalCache
        connect unless @@server
        if @@server.terminated?
          @logger.warn("Client: Server is being terminated")
          @@server = LocalCache.new
        end
      rescue Exception => e
          @logger.error("\n******************************************\n" +
                        "Exception: #{e.to_s} - (#{e.class})\n" +
                        "Client: Cannot connect to server, please check your configuration\n" +
                        "----------------BACKTRACE-----------------\n" +
                                  e.backtrace.join("\n") + "\n" +
                        "-------------------END--------------------\n" +
                        "\n******************************************\n" )
          # Redirect new jobs to cache
          @@server = LocalCache.new
      end
    end
    
    def connect(client_options = {:server => :master})
      @client_options ||= client_options
      @logger.debug("Client: Client options are #{@client_options.inspect}")
      server_options = {:host => @config.server(client_options[:server]).host, :port => @config.server(client_options[:server]).port}
      @logger.debug("Client: Server options are #{server_options.inspect}")
      
      unless @client_options[:local]
        uri = "druby://#{server_options[:host]}:#{server_options[:port]}"
        @logger.info("Client: Connecting to remote")
        @logger.debug("Client: Server URI #{uri}")
        DRb.start_service()
        @@server = DRbObject.new(nil, uri)
      else
        @logger.info("Client: Connecting to local")
        @@server = ActiveBackground::Manager.instance
      end
      
      #TODO: retrieve from local cache
    end

    def wait_for_server
      @logger.info("Client: waiting till server is completed with processing jobs")
      @@server.wait()
    end
    
    def terminate_server
      @logger.info("Client: Terminating servers (and slave servers)")
      @@server.terminate()
    end
    
    private
      def method_missing(method, *args, &block)
        # puts method.to_s
      end
  end
  
  class LocalCache
    def add_job(key, job)
      File.open(File.dirname(__FILE__) + "/../../workspace/local/#{key}.yaml", "w") {|f| YAML.dump(job.dump, f)} unless job.dump
    end
    
    def terminated?
      false
    end
    
    def job_count
      0
    end
      
    def method_missing(method, *args, &block)
      # method.to_s + args.to_s
    end
  end
end